package com.dragon.english_practice_back.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dragon.english_practice_back.service.GrammarsScheduleService;
import com.dragon.english_practice_back.service.ResponseAnalysisService;
import com.dragon.english_practice_back.service.WordScheduleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.ai.deepseek.api.ResponseFormat;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
@EnableAsync
@AllArgsConstructor
public class ResponseAnalysisServiceImpl implements ResponseAnalysisService {
    WordScheduleService wordScheduleService;
    GrammarsScheduleService grammarsScheduleService;
    TokenUsageServiceImpl tokenUsageServiceImpl;
    ChatClient deepSeekChatClient;
    @Override
    @Async
    public void analysis(int userId, String question, String response) {

        // 获取用户的语法表
        List<Map<String, Object>> grammarsSchedule = grammarsScheduleService.getGrammarsSchedule(userId);
        // 去掉熟练度这一项
        for (Map<String, Object> grammar : grammarsSchedule) {
            grammar.remove("proficiency");
        }
        log.debug("userID: {}, grammarsSchedule: {}", userId, JSONUtil.toJsonStr(grammarsSchedule));
        // grammars的map解释
        String grammarsScheduleMapFormat = "id:语法id,grammar:语法,example:示例或简单的语法描述";

        // 获取用户的单词表
        List<Map<String, Object>> todayWordSchedule = wordScheduleService.getTodayWordSchedule(userId);
        // 去掉熟练度这一项
        for (Map<String, Object> word : todayWordSchedule) {
            word.remove("proficiency");
        }
        log.debug("userId: {}, todayWordSchedule: {}", userId, JSONUtil.toJsonStr(todayWordSchedule));
        // word的map解释
        String wordScheduleMapFormat = "id:单词id,word:单词,meaning:单词意思";


        // 希望得到的JSON格式:
        String jsonFormat = """
                
                {
                    "correctGrammarIds": [
                        "正确理解或使用的语法id1",
                        "正确理解或使用的语法id2"
                    ],
                    "wrongGrammarIds": [
                        "错误理解或使用的语法id3",
                        "错误理解或使用的语法id4"
                    ],
                    "correctWordIds": [
                        "正确理解或使用单词的id1",
                        "正确理解或使用单词的id2"
                    ],
                    "wrongWordIds": [
                        "错误理解或使用单词的id3",
                        "错误理解或使用单词的id4"
                    ],
                    "contentType": "上下文的类型（翻译或日常对话）"
                }
                
                """;
        String jsonFormatExplanation = """
                correctGrammarIds是用户正确理解或使用的语法id列表，
                wrongGrammarIds是用户错误理解或使用的语法id列表，
                correctWordIds是用户正确理解或使用单词的id列表，
                wrongWordIds是用户错误理解或使用单词的id列表。
                contentType是上下文的类型，可能是翻译或日常对话。
                
                """;
        // 构造提问prompt
        String systemPrompt = """
                你是一个英语老师，你的任务是分析用户的回答的语法和单词的使用和理解是否正确，你需要根据语法表和单词表指出正确或错误的语法和单词。
                下面有JSON格式的语法和单词的列表，你需要根据这些列表来作答，你的回答需要使用到语法表和单词表的元素的id。
                用户的消息给两个东西，一个是题目question，一个是回答response，用户可能是在解答翻译题目，也可能是根据题目进行日常对话。
                如果题目和回答使用的语言（英文或中文）不一样，那么用户的回答可能是翻译。
                如果题目和回答使用的都是英文，那么用户的回答可能是日常对话。
                """
                + """
                你的回答是一个JSON格式的字符串，示例如下：
                """
                + jsonFormat
                + """
                其中，
                """
                + jsonFormatExplanation
                + """
                
                JSON格式的语法列表如下：
                
                """
                + JSONUtil.toJsonStr(grammarsSchedule)
                + "其中：" + grammarsScheduleMapFormat
                + """
                
                JSON格式的单词表如下：
                
                """
                + JSONUtil.toJsonStr(todayWordSchedule)
                + "其中：" + wordScheduleMapFormat
                ;
        String userPrompt = "question:" + question + "\nresponse" + response;
        Message systemMessage = new SystemMessage( systemPrompt);
        Message userMessage = new UserMessage(userPrompt);

        String content = this.deepSeekChatClient.prompt().messages(List.of(systemMessage, userMessage))
                .options(DeepSeekChatOptions.builder()
                        .temperature(0.5)
                        .responseFormat(ResponseFormat.builder().type(ResponseFormat.Type.JSON_OBJECT).build())
                        .build())
                .call().content();


        List<Integer> correctGrammarIdsList = null;
        List<Integer> wrongGrammarIdsList = null;
        List<Integer> correctWordIdsList = null;
        List<Integer> wrongWordIdsList = null;
        // 解析jsonContent，获取需要的信息
        if (content != null && JSONUtil.isTypeJSON(content)){
            JSONObject root = JSONUtil.parseObj(content);
            log.info("userId: {}, root: {}", userId, root.toStringPretty());
            JSONArray correctGrammarIds = root.getJSONArray("correctGrammarIds");
            JSONArray wrongGrammarIds = root.getJSONArray("wrongGrammarIds");
            JSONArray correctWordIds = root.getJSONArray("correctWordIds");
            JSONArray wrongWordIds = root.getJSONArray("wrongWordIds");

            if (correctGrammarIds != null && !correctGrammarIds.isEmpty()){
                correctGrammarIdsList = correctGrammarIds.toList(Integer.class);
            }
            if (wrongGrammarIds != null && !wrongGrammarIds.isEmpty()){
                wrongGrammarIdsList = wrongGrammarIds.toList(Integer.class);
            }
            if (correctWordIds != null && !correctWordIds.isEmpty()){
                correctWordIdsList = correctWordIds.toList(Integer.class);
            }
            if (wrongWordIds != null && !wrongWordIds.isEmpty()){
                wrongWordIdsList = wrongWordIds.toList(Integer.class);
            }
        }
        // 更新熟练度
        if (correctGrammarIdsList != null && !correctGrammarIdsList.isEmpty()) {
            log.info("userId: {}, updateGrammarsProficiency correct: {}", userId, correctGrammarIdsList);
            grammarsScheduleService.updateGrammarsProficiency(userId, correctGrammarIdsList, true);
        }
        if (wrongGrammarIdsList != null && !wrongGrammarIdsList.isEmpty()){
            log.info("userId: {}, updateGrammarsProficiency wrong: {}", userId, wrongGrammarIdsList);
            grammarsScheduleService.updateGrammarsProficiency(userId, wrongGrammarIdsList, false);
        }
        if (correctWordIdsList != null && !correctWordIdsList.isEmpty()){
            log.info("userId: {}, updateWordProficiency correct: {}", userId, correctWordIdsList);
            wordScheduleService.updateWordProficiency(userId, correctWordIdsList, true);
        }
        if (wrongWordIdsList != null && !wrongWordIdsList.isEmpty()){
            log.info("userId: {}, updateWordProficiency wrong: {}",userId,  wrongWordIdsList);
            wordScheduleService.updateWordProficiency(userId, wrongWordIdsList, false);
        }
    }
}
